/**
 *
 */
package com.aiou.security.app.validate.code.impl;

import com.aiou.security.properties.SecurityConstants;
import com.aiou.security.properties.SecurityProperties;
import com.aiou.security.validate.code.ValidateCode;
import com.aiou.security.validate.code.ValidateCodeException;
import com.aiou.security.validate.code.ValidateCodeRepository;
import com.aiou.security.validate.code.ValidateCodeType;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.request.ServletWebRequest;

import java.util.concurrent.TimeUnit;

/**
 * @author zyb
 */
@Component
public class RedisValidateCodeRepository implements ValidateCodeRepository {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private SecurityProperties securityProperties;

    private AntPathMatcher pathMatcher = new AntPathMatcher();

    @Override
    public void save(ServletWebRequest request, ValidateCode code, ValidateCodeType type) {
        long expireIn = 60;
        if (type.equals(ValidateCodeType.SMS)) {
            expireIn = securityProperties.getCode().getSms().getExpireIn().toMillis();
        } else if (type.equals(ValidateCodeType.IMAGE)) {
            expireIn = securityProperties.getCode().getImage().getExpireIn().toMillis();
        }
        redisTemplate.opsForValue().set(buildKey(request, type), code, expireIn, TimeUnit.MILLISECONDS);
    }


    @Override
    public ValidateCode get(ServletWebRequest request, ValidateCodeType type) {
        Object value = redisTemplate.opsForValue().get(buildKey(request, type));
        return (ValidateCode) value;
    }

    @Override
    public void remove(ServletWebRequest request, ValidateCodeType type) {
        redisTemplate.delete(buildKey(request, type));
    }

    /**
     * @param request
     * @param type
     * @return
     */
    private String buildKey(ServletWebRequest request, ValidateCodeType type) {
        String uri = request.getRequest().getRequestURI();
        String suffix = null;
        if (pathMatcher.match(uri, SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_MOBILE)) {
            suffix = request.getParameter("mobile");
            if (StringUtils.isBlank(suffix)) {
                throw new ValidateCodeException("mobile不能为空");
            }
        }
        if (pathMatcher.match(uri, SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_FORM)) {
            suffix = request.getParameter("username");
            if (StringUtils.isBlank(suffix)) {
                throw new ValidateCodeException("username不能为空");
            }
        }

        return "code:" + type.toString().toLowerCase() + ":" + suffix;
    }

}
